/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.lucava.boatskeeper.client;

import com.google.gwt.user.client.History;
import com.google.gwt.user.client.ui.RootLayoutPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import net.customware.gwt.dispatch.client.DispatchAsync;
import net.customware.gwt.presenter.client.Display;
import net.customware.gwt.presenter.client.EventBus;
import net.customware.gwt.presenter.client.Presenter;
import net.customware.gwt.presenter.client.place.Place;
import net.customware.gwt.presenter.client.place.PlaceRequestEvent;
import net.customware.gwt.presenter.client.place.PlaceRequestHandler;
import net.customware.gwt.presenter.client.widget.WidgetDisplay;
import org.lucava.boatskeeper.client.event.*;
import org.lucava.boatskeeper.client.presenter.ViewPresenter;
import org.lucava.boatskeeper.client.presenter.boat.BoatsPresenter;
import org.lucava.boatskeeper.client.presenter.boat.EditBoatPresenter;
import org.lucava.boatskeeper.client.presenter.boat.ShowBoatPresenter;
import org.lucava.boatskeeper.client.presenter.user.UserAuthPresenter;
import org.lucava.boatskeeper.client.view.boat.BoatsView;
import org.lucava.boatskeeper.client.view.boat.EditBoatView;
import org.lucava.boatskeeper.client.view.boat.ShowBoatView;
import org.lucava.boatskeeper.client.view.user.UserAuthView;

/**
 *
 * @author glenn
 */
public class AppController implements Presenter, PlaceRequestHandler {

    private EventBus eventBus;
    private MainLayout layout;
    private ViewPresenter<? extends WidgetDisplay> presenter;
    private final DispatchAsync dispatcher;
    private final UserAuthPresenter authPresenter;
    //private final EditBoatPresenter editBoatPresenter;
    // private final ShowBoatPresenter showBoatPresenter;
    private final List<ViewPresenter> presenters;

    public AppController(EventBus eventBus, DispatchAsync dispather) {
        this.eventBus = eventBus;
        this.dispatcher = dispather;

        PlaceMapper.configure();

        authPresenter = new UserAuthPresenter(dispatcher, eventBus, new UserAuthView());

        presenters = new ArrayList<ViewPresenter>();
        presenters.add(new BoatsPresenter(dispatcher, eventBus, new BoatsView()));
        presenters.add(new EditBoatPresenter(dispatcher, eventBus, new EditBoatView()));
        presenters.add(new ShowBoatPresenter(dispatcher, eventBus, new ShowBoatView()));

        this.presenter = authPresenter;
        bind();
    }

    @Override
    public void bind() {
        eventBus.addHandler(PlaceRequestEvent.getType(), this);

        eventBus.addHandler(AddEvent.TYPE, new AddEventHandler() {
            @Override
            public void onAdd(AddEvent event) {
                doAdd(event.PLACE);
            }
        });

        eventBus.addHandler(EditEvent.TYPE, new EditEventHandler() {
            @Override
            public void onEdit(EditEvent event) {
                doEdit(event.PLACE, event.getId());
            }
        });

        eventBus.addHandler(UpdatedEvent.TYPE, new UpdatedEventHandler() {
            @Override
            public void onUpdated(UpdatedEvent event) {
                doUpdated(event.PLACE);
            }
        });

        eventBus.addHandler(EditCancelledEvent.TYPE, new EditCancelledEventHandler() {
            @Override
            public void onEditCancelled(EditCancelledEvent event) {
                doEditCancelled(event.PLACE);
            }
        });

        eventBus.addHandler(ShowCancelledEvent.TYPE, new ShowCancelledEventHandler() {
            @Override
            public void onShowCancelled(ShowCancelledEvent event) {
                doShowCancelled(event.PLACE);
            }
        });
    }

    private void doAdd(Place place) {
        History.newItem(place.getId());
    }

    private void doEditCancelled(Place place) {
        History.newItem(place.getId());
    }

    private void doShowCancelled(Place place) {
        History.newItem(place.getId());
    }

    protected void doUpdated(Place place) {
        History.newItem(place.getId());
    }

    private void doEdit(Place place, Integer boatId) {
        History.newItem(place.requestWith("id", boatId.toString()).toString());
    }

    public void setLayout(final MainLayout layout) {
        this.layout = layout;
    }
    /*
     public void go(final MainLayout layout) {

     this.layout = layout;

     if ("".equals(History.getToken())) {
     History.newItem(presenter.getPlace().getId());
     } else {
     History.fireCurrentHistoryState();
     }

     }*/

    @Override
    public void onPlaceRequest(PlaceRequestEvent event) {
        String id = event.getRequest().getPlace().getId();

        Iterator<ViewPresenter> itPre = presenters.iterator();

        while (itPre.hasNext()) {
            ViewPresenter pre = itPre.next();
            if (id.equals(pre.getPlace().getId())) {
                presenter = pre;
            }
        }
        refreshDisplay();
    }

    @Override
    public void refreshDisplay() {
        Widget toDisplay;
        if (!UserSession.getInstance().isAuthenticated()) {
            SimplePanel authContainer = new SimplePanel();
            authPresenter.go(authContainer);
            toDisplay = authContainer;
        } else {
            layout.clear();
            toDisplay = layout;
            if (presenter != null) {
                presenter.go(layout.getContentPanel());
            }
        }
        RootLayoutPanel.get().clear();
        RootLayoutPanel.get().add(toDisplay);
    }

    @Override
    public Display getDisplay() {
        return null;
    }

    @Override
    public void revealDisplay() {
    }

    @Override
    public void unbind() {
        Iterator<ViewPresenter> itPre = presenters.iterator();
        while (itPre.hasNext()) {
            ViewPresenter pre = itPre.next();
            pre.unbind();
        }
    }
}
